package controller

import (
	"net/http"

	"project/study-go/ecode"
	"project/study-go/validate"

	"github.com/gorilla/sessions"

	"project/study-go/http/base/session"
	"project/study-go/http/middleware"
	"project/study-go/logic"
	"project/study-go/model"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

//AccountController 自定义account controller
type AccountController struct{}

//RegisterRoute 注册路由
func (s *AccountController) RegisterRoute(g *gin.RouterGroup) {
	account := g.Group("/account")
	account.Any("/register", Register)
	account.Any("/login", Login)
	account.Any("/forgetpwd", ForgetPasswd)
	account.Any("/resetpwd", ResetPasswd)
	account.POST("/chgpwd", middleware.SessionAuth(), ChangePasswd)
	account.GET("/logout", middleware.SessionAuth(), Logout)
}

//Register 注册
func Register(c *gin.Context) {
	//如果不是POST请求，返回注册html页面
	if c.Request.Method != http.MethodPost {
		c.HTML(200, "register.html", nil)
		return
	}
	//校验用户注册信息是否规范
	userReg := model.UserRegistry{}
	if err := c.ShouldBindWith(&userReg, binding.Form); err != nil {
		c.JSON(http.StatusBadRequest, ecode.Response{
			Code: http.StatusBadRequest,
			Msg:  validate.ValidateTranslation(err),
			Data: nil,
		})
		return
	}

	//用于在处理链中校验这些注册参数
	c.Set("username", userReg.Username)
	c.Set("password", userReg.Password)
	c.Set("email", userReg.Email)

	//检查邮箱与用户名是否被注册
	if err := logic.DefaultAccount.UserRegisterExist(c); err != nil {
		c.JSON(http.StatusBadRequest, ecode.Response{
			Code: 400,
			Msg:  err.Error(),
		})
		return
	}

	//创建 user 入库
	err := logic.DefaultAccount.CreateUser(c)
	if err != nil {
		c.JSON(http.StatusInternalServerError, ecode.Response{
			Code: 500,
			Msg:  "StatusInternalServerError",
		})
		return
	}

	//种cookie
	sess, err := session.SStore.Get(c.Request, "SESSIONID")
	if err != nil {
		c.JSON(500, ecode.Response{
			Code: 500,
			Msg:  "StatusInternalServerError",
		})
		return
	}

	//将session保存到redis中
	sess.Values["uid"] = c.GetString("uid")
	err = sess.Save(c.Request, c.Writer)
	if err != nil {
		c.JSON(500, ecode.Response{
			Code: 500,
			Msg:  "StatusInternalServerError",
		})
		return
	}

	c.JSON(http.StatusOK, ecode.Response{
		Code: 200,
		Msg:  "注册成功",
	})
}

//Login 登录
func Login(c *gin.Context) {
	//如果不是POST请求，返回登录html页面
	if c.Request.Method != http.MethodPost {
		c.HTML(200, "login.html", nil)
		return
	}
	//校验用户表单是否规范
	userLogin := model.UserLogin{}
	if err := c.ShouldBindWith(&userLogin, binding.Form); err != nil {
		c.JSON(400, ecode.Response{
			Code: 400,
			Msg:  validate.ValidateTranslation(err),
			Data: nil,
		})
		return
	}

	//登录 logic
	errCode := logic.DefaultAccount.Login(c, userLogin)
	if errCode.Err != nil {
		c.JSON(errCode.Code, ecode.Response{
			Code: errCode.Code,
			Msg:  errCode.Err.Error(),
		})
		return
	}

	//种cookie
	data := map[interface{}]interface{}{}
	data["uid"] = c.GetString("uid")
	data["username"] = c.GetString("username")

	err := session.SetSession(c, "SESSIONID", data)
	if err != nil {
		c.JSON(500, ecode.Response{
			Code: 500,
			Msg:  err.Error(),
		})
		return
	}

	//成功
	c.JSON(http.StatusOK, ecode.Response{
		Code: 200,
		Msg:  "登录成功",
	})
}

//Logout 注销，删除session
func Logout(c *gin.Context) {
	err := session.DeleteSession(c, "SESSIONID")
	if err != nil {
		c.JSON(500, ecode.Response{
			Msg: ecode.ErrInternalError,
		})
		return
	}

	c.JSON(http.StatusOK, ecode.Response{
		Msg: "Logout Success",
	})
}

//ChangePasswd 在已认证状态下修改密码
func ChangePasswd(c *gin.Context) {
	//获取session
	session, ok := c.Get("SESSIONID")
	if !ok {
		c.JSON(403, ecode.Response{
			Code: 403,
			Msg:  "StatusForbidden",
			Data: nil,
		})
		return
	}

	chgpwd := &model.ChangePassword{}
	err := c.ShouldBindWith(chgpwd, binding.Form)
	if err != nil {
		c.JSON(400, ecode.Response{
			Code: 400,
			Msg:  validate.ValidateTranslation(err),
		})
		return
	}

	uid := session.(*sessions.Session).Values["uid"]
	errCode := logic.DefaultAccount.ChgPasswd(uid.(string), chgpwd.Oldpassword, chgpwd.Newpassword)
	if errCode.Err != nil {
		c.JSON(errCode.Code, ecode.Response{
			Code: errCode.Code,
			Msg:  errCode.Err.Error(),
		})
		return
	}

	c.JSON(200, ecode.Response{
		Code: 200,
		Msg:  "chgpwd success",
	})
}

//ForgetPasswd 忘记密码
func ForgetPasswd(c *gin.Context) {

}

//ResetPasswd 重置密码
func ResetPasswd(c *gin.Context) {

}
